/* Based on bgc.h
   From Cameron McBride, Copyright (c) 2011.
   Explicit permission granted to distribute with Rockstar under the GPLv3.
*/

#pragma once
#ifndef BGC_HEADER_DEFINED
#define BGC_HEADER_DEFINED 1

#include <inttypes.h>
#include <limits.h>

#if LONG_MAX < LLONG_MAX
#warning Compiling in 32-bit mode is not recommended; correct operation with datasets larger than 2GB is not guaranteed.
#endif


#define BGC_MAGIC ((uint64_t)0x1234567801010101ll)
#define BGC2_HEADER_SIZE 1024

typedef struct bgc2_output_header {
  uint64_t magic;      /* A magic number to identify this as a BGC file. */
  int64_t  version;    /* File version number. */

  int64_t num_files;       /* number of files output is distributed into */
  int64_t file_id;         /* this files ID (number) if multiple files are output */
  int64_t snapshot;        /* Snapshot ID */
  int64_t format;          /* output particle data format identifier, see enum pdata_format below */
  int64_t format_gdata;    /* output group data format identifier, see enum gdata_format below */

  int64_t first_valid_group_id;  /* ID of the first valid group (0 or 1). */
  int64_t first_group_id;  /* ID of the first group stored in this file */
  int64_t ngroups;         /* number of groups stored LOCALLY in this file */
  int64_t ngroups_total;   /* number of groups stored GLOBALLY over all output BGC files */
  int64_t min_group_part;  /* minimum number of particles in a group */

  int64_t npart;           /* number of particles bound in groups LOCALLY in this file */
  int64_t npart_total;     /* number of particles bound in groups GLOBALLY over all output BGC files */
  int64_t npart_orig;      /* total number of particles of input */
  int64_t valid_part_ids;  /* keep track of whether we read in Gadget IDs or ignored them (for Roman's lightcone) */

  int64_t max_npart;       /* maximum number of particles in one group LOCALLY in this file */
  int64_t max_npart_total; /* maximum number of particles in one group GLOBALLY over all output BGC files */

  double linkinglength;

  double time;             /* time of the input snapshot */
  double redshift;         /* redshift of the input snapshot */
  double Omega0;           /* Matter density at z=0 */
  double OmegaLambda;      /* Dark energy density at z=0 */

  double BoxSize;
  double bounds[6];        /* Spatial bounds of the halo centers contained in this file */

  /* these define the units, irrelevant unless binding energies are calculated */
  double Hubble0;          /* in whatever units are used */
  double GravConst;        /* in whatever units are used */
  double part_mass;        /* mass of particles if only one type exists */

  uint8_t padding[BGC2_HEADER_SIZE - (33*8)];
} BGC2_HEADER;

enum gdata_format {
  GDATA_FORMAT_ID = 10,
  GDATA_FORMAT_RM = 20,
  GDATA_FORMAT_RMPV = 30,
  GDATA_FORMAT_RMPVMAX = 40,
};

typedef struct {
 int64_t id;
 int64_t parent;
 uint64_t num_part;
 float radius;  /* halo radius. SO is well defined -- FOF not so much */
 float mass;
 float pos[3];
 float vel[3];
 float vmax, rvmax;
} GROUP_DATA_RMPVMAX;

enum pdata_format {
    PDATA_FORMAT_NULL = 0,
    PDATA_FORMAT_ID = 10,
    PDATA_FORMAT_IDBE = 15,
    PDATA_FORMAT_POS = 20,
    PDATA_FORMAT_POSBE = 25,
    PDATA_FORMAT_PV = 30,
    PDATA_FORMAT_PVBE = 35,
    PDATA_FORMAT_PVM = 40,
    PDATA_FORMAT_PVMBE = 45,
    PDATA_FORMAT_GPVM = 50
};

typedef struct {
    int64_t part_id;
    float pos[3];
    float vel[3];
} PARTICLE_DATA_PV;

#endif

// vim: ts=8 sw=4 sts=4 expandtab
